package com.burybell.storage.controller.common;

import com.burybell.storage.domain.CommonResult;
import com.burybell.storage.domain.Storage;
import com.burybell.storage.system.MimeMap;
import com.burybell.storage.system.StorageTemplate;
import com.burybell.storage.system.bean.BurstInputStream;
import com.burybell.storage.utils.ResponseUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@Slf4j
public class CommonController {

    @Resource
    private StorageTemplate storageTemplate;

    @Resource
    private MimeMap mimeMap;

    @PostMapping("/common/upload/{scene}")
    public CommonResult upload(@RequestParam("file") MultipartFile file,@PathVariable String scene) {
        try {
            Storage storage = storageTemplate.set(scene, file.getOriginalFilename(), file.getSize(), file.getInputStream());
            return new CommonResult(200,"upload success",storage);
        } catch (IOException e) {
            return new CommonResult(401,"upload fail");
        }
    }

    @PostMapping("/common/upload")
    public CommonResult upload(@RequestParam("file") MultipartFile file) {
        try {
            Storage storage = storageTemplate.set("default", file.getOriginalFilename(), file.getSize(), file.getInputStream());
            return new CommonResult(200,"upload success",storage);
        } catch (IOException e) {
            return new CommonResult(401,"upload fail");
        }
    }

    @GetMapping("/view/{scene}/{year}/{month}/{day}/{sid}")
    public void view(@PathVariable String scene, @PathVariable Integer year,
                     @PathVariable Integer month, @PathVariable Integer day,
                     @PathVariable String sid, HttpServletResponse response) {
        BurstInputStream burstInputStream = storageTemplate.get(scene, year, month, day, sid);
        Storage storage = burstInputStream.getStorage();
        ResponseUtils.doViewNameSuffix(mimeMap,response,storage.getDefinition(),storage.getSuffix());
        try {
            ServletOutputStream outputStream = response.getOutputStream();
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = burstInputStream.read(bytes)) != -1) {
                outputStream.write(bytes,0,len);
            }
            burstInputStream.close();
        } catch (IOException e) {
            log.info("view-" + storage.getDefinition());
        }
    }

    @GetMapping("/download/{scene}/{year}/{month}/{day}/{sid}")
    public void download(@PathVariable String scene, @PathVariable Integer year,
                         @PathVariable Integer month, @PathVariable Integer day,
                         @PathVariable String sid, HttpServletRequest request, HttpServletResponse response) {
        BurstInputStream burstInputStream = storageTemplate.get(scene, year, month, day, sid);
        Storage storage = burstInputStream.getStorage();
        ResponseUtils.doDownloadNameSuffix(mimeMap,response,storage.getDefinition(),storage.getSuffix());
        try {
            ServletOutputStream os = response.getOutputStream();
            long start = 0;
            String range = request.getHeader("range");
            if (range != null) {
                System.out.println("range=" + range);
                String rg = range.split("=")[1];
                start = Long.parseLong(rg.split("-")[0]);
                response.setStatus(206);
            }
            response.setHeader("Accept-Ranges", "bytes");
            response.setHeader("Content-Range", "bytes  " + start + "-" + (storage.getSize() - 1) + "/" + storage.getSize());
            response.setHeader("Content-Length", " " + storage.getSize());
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = burstInputStream.read(buffer, 0, buffer.length)) != -1) {
                os.write(buffer, 0, len);
                os.flush();
            }
            os.close();
            burstInputStream.close();
        } catch (IOException e) {
            log.info("download-" + storage.getDefinition());
        }
    }
}
